<template>
  <el-select
    ref="searchSelect"
    v-model="innerValue"
    v-el-select-loadmore="loadMore"
    :multiple="multiple"
    :disabled="disabled"
    filterable
    clearable
    default-first-option
    remote
    :remote-method="remoteLoad"
    :placeholder="placeholder"
    @input.native="filterData"
    @blur="onBlur"
    @clear="clearAcct"
    @change="changeSelect"
    @visible-change="initAcctSelectParamAcctName($event)"
  >
    <el-option v-for="item in optionListView" :key="item[keys]" :label="item[label]" :value="item[keys]" />
  </el-select>
</template>
<script>
export default {
  directives: {
    'el-select-loadmore': {
      bind(el, binding) {
        // 获取element-ui定义好的scroll盒子
        const DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
        DOM.addEventListener('scroll', function() {
          /**
                      * scrollHeight 获取元素内容高度(只读)
                      * scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
                      * clientHeight 读取元素的可见高度(只读)
                      * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
                      * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
                      */
          const condition = this.scrollHeight - (Math.ceil(this.scrollTop) + 10) <= this.clientHeight
          if (condition) {
            binding.value()
          }
        })
      }
    }
  },
  props: {
    value: [String, Number],
    multiple: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    pageSize: {
      type: Number,
      default: 10
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    remoteDataFatch: {
      type: Function,
      default: () => {
        return Function
      }
    },
    keys: {
      type: String,
      default: 'key'
    },
    label: {
      type: String,
      default: 'label'
    }
  },
  data() {
    return {
      optionList: [],
      optionListView: [],
      pageNum: 1,
      innerValue: this.multiple ? [] : '',
      selectdOption: [],
      query: '' // 字段名
    }
  },
  watch: {
    value: {
      handler() {
        this.innerValue = this.multiple ? (this.value ? this.value.split(',') : []) : this.value
        // 本地没有此选项label
        if (this.selectdOption.findIndex(v => v[this.keys] === this.value) < 0) {
          this.remoteDataFatch({ ids: this.value }).then(res => {
            if (res && res.data) {
              this.selectdOption = res.data
              this.optionListView = this.merge(this.optionList, this.selectdOption)
            }
          })
        }
      },
      immediate: true
    },
    innerValue() {
      const index = this.optionListView.findIndex(v => v[this.keys] === this.innerValue)
      if (index >= 0) {
        this.selectdOption = [this.optionListView[index]]
      }
      this.$emit('input', this.multiple ? this.innerValue.join(',') : this.innerValue)
    }
  },
  created() {
    this.loadOptions()
  },
  methods: {
    changeSelect(e) {
      this.$emit('change', e)
    },
    // 对输入字符串控制
    filterData() {
      var str = this.$refs.searchSelect.$data.selectedLabel// 此属性得到输入的文字
      // 控制的js
      if (str.length > 50) {
        this.$refs.searchSelect.$data.selectedLabel = str.substr(0, 50)
      }
    },
    onBlur() {
      this.query = ''
      this.pageNum = 1
      // return this.loadOptions()
    },
    clearAcct() {
      this.query = ''
    },
    initAcctSelectParamAcctName(callback) {
      if (callback === true) {
        this.pageNum = 1
        this.query = ''
        return this.loadOptions()
      }
    },
    remoteLoad(query) {
      this.query = query
      this.pageNum = 1
      return this.loadOptions()
    },
    loadOptions() {
      return this.remoteDataFatch({ // 后台接口
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        query: this.query // 字段名
      }).then(res => {
        if (!res.data) res.data = res.rows
        if (this.pageNum === 1) {
          this.optionList = res.data
        } else {
          for (const item of res.data) {
            if (this.optionList.findIndex(i => i[this.keys] === item[this.keys]) < 0) {
              this.optionList.push(item)
            }
          }
          // this.optionList = [...this.optionList, ...res.data]
        }
        if (this.query == null) {
          this.optionListView = this.merge(this.optionList, this.selectdOption)
        } else {
          this.optionListView = this.optionList
        }
      })
    },
    remoteFilter() {
    },
    merge(optionList, selectedList) {
      let result = [...optionList]
      for (var item of selectedList) {
        if (result.findIndex(i => i[this.keys] === item[this.keys]) < 0) {
          result = [item, ...result]
        }
      }
      return result
    },
    loadMore() {
      console.log(111)
      this.pageNum++
      this.loadOptions()
    }
  }
}
</script>
